package com.wutong.resonance.model.plugin;

import com.wutong.resonance.model.audio.AudioData;
import com.wutong.resonance.model.audio.AudioParams;
import com.wutong.resonance.model.util.LogUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 插件基类
 * @author wutong
 */
@Slf4j
@Setter
@Getter
public abstract class Plugin implements IPlugin {

    public enum PluginStatus {
        STOP,
        ERROR,
        LOADING
    }
    /**
     * 插件构造函数
     * @param pluginName 插件名称
     * @param pluginDesc 插件描述
     */
    public Plugin(String pluginName, String pluginDesc, AudioParams audioParams) {
        this.pluginName = pluginName;
        this.pluginDesc = pluginDesc;
        this.audioParams = audioParams;
    }

    /**
     * 插件构造函数，默认插件描述为"该插件没有任何的描述。[This plugin does not have a description.]"
     * @param pluginName 插件名称
     */
    public Plugin(String pluginName, AudioParams audioParams) {
        this(pluginName, "该插件没有任何的描述。[This plugin does not have a description.]", audioParams);
    }

    /**
     * 插件ID
     */
    private static final AtomicInteger PLUGIN_ID = new AtomicInteger(0);

    protected final int pluginId = PLUGIN_ID.incrementAndGet();

    /**
     * 插件名称
     */
    protected String pluginName;

    /**
     * 插件描述
     */
    protected String pluginDesc;

    /**
     * 插件状态
     */
    protected PluginStatus pluginStatus = PluginStatus.STOP;

    protected AudioParams audioParams;

    /**
     * 插件初始化
     */
    @Override
    public void init() {
        if (pluginStatus != PluginStatus.STOP && pluginStatus != PluginStatus.ERROR) {
            log.error("插件 {} 已初始化，请勿重复初始化。", pluginName);
            return;
        }
        if (pluginStatus == PluginStatus.ERROR) {
            log.error("插件 {} 异常，请检查插件配置。", pluginName);
            return;
        }
        log.info("插件 {} 初始化中...", pluginName);
        try {
            initPlugin(audioParams);
        } catch (Exception e) {
            log.error("插件 {} 初始化失败，原因：{}", pluginName, e.getMessage());
            pluginStatus = PluginStatus.ERROR;
            return;
        }
        log.info("插件 {} 初始化成功。", pluginName);
        pluginStatus = PluginStatus.LOADING;
    }

    /**
     * 插件初始化的具体实现
     */
    protected abstract void initPlugin(AudioParams audioParams);

    /**
     * 插件销毁
     */
    public void unload() {
        if (pluginStatus == PluginStatus.STOP) {
            log.error("插件 {} 未加载，无法卸载。", pluginName);
            return;
        }
        try {
            unloadPlugin();
        } catch (Exception e) {
            log.error("插件 {} 卸载失败，原因：{}", pluginName, e.getMessage());
            pluginStatus = PluginStatus.ERROR;
            return;
        }
        log.info("插件 {} 卸载成功。", pluginName);
        pluginStatus = PluginStatus.STOP;
    }

    /**
     * 显示插件
     */
    @Override
    public void close() {
        unload();
    }

    /**
     * 插件卸载的具体实现
     */
    protected abstract void unloadPlugin();

    /**
     * 插件处理
     * @param audioData 音频数据
     * @return 处理后的音频数据
     */
    public AudioData process(AudioData audioData) {
        return switch (pluginStatus) {
            case LOADING -> processPlugin(audioData);
            case ERROR -> {
                LogUtil.showOnce(pluginName, () -> log.error("插件 {} 异常，请检查插件。", pluginName));
                yield audioData;
            }
            case STOP -> {
                LogUtil.showOnce(pluginName, () -> log.error("插件 {} 未加载，请先初始化。", pluginName));
                yield audioData;
            }
        };
    }

    protected abstract AudioData processPlugin(AudioData audioData);
}
